﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RaytracerLib.MathLib;
using YAXLib;
using TomanuExtensions;

namespace RaytracerLib.UVMappers
{
    public class ConicalUVMapper : UVMapper
    {
        private double m_radius;
        private double m_height;
        private double m_scale;

        [YAXNode]
        public double Radius
        {
            get
            {
                return m_radius;
            }
            set
            {
                m_radius = value;
                UpdateScale();
            }
        }

        [YAXNode]
        public double Height
        {
            get
            {
                return m_height;
            }
            set
            {
                m_height = value;
                UpdateScale();
            }
        }

        [YAXOnDeserialized]
        private void UpdateScale()
        {
            m_scale = Radius / Math.Sqrt(Radius * Radius + Height * Height);
        }

        public ConicalUVMapper(double a_radius = 0, double a_height = 0)
        {
            Radius = m_radius;
            Height = a_height;
        }

        public override Vector2 Map(Vector3 a_uvw)
        {
            if (a_uvw.Y.IsAlmostEquals(1))
                return new Vector2(a_uvw.X, a_uvw.Z);
            else
            {
                double alpha = (MathExtensions.PI - Math.Atan2(a_uvw.X - 0.5, 0.5 - a_uvw.Z)) * m_scale;
                return new Vector2(0.5 - 0.5 * a_uvw.Y * Math.Cos(alpha),
                                    0.5 - 0.5 * a_uvw.Y * Math.Sin(alpha));
            }
        }

        public override UVMappingMethod Method
        {
            get 
            {
                return UVMappingMethod.Conical;
            }
        }

        public override string ToString()
        {
            return String.Format("Conical uv mapper: H: {0}, R: {1}", Height, Radius);
        }
    }
}
